home *** CD-ROM | disk | FTP | other *** search
- Path: keats.ugrad.cs.ubc.ca!not-for-mail
- From: c2a192@ugrad.cs.ubc.ca (Kazimir Kylheku)
- Newsgroups: comp.lang.c
- Subject: Re: Fastest way to computer log(base2) of x?
- Date: 28 Jan 1996 11:11:44 -0800
- Organization: Computer Science, University of B.C., Vancouver, B.C., Canada
- Message-ID: <4eghpgINNn5c@keats.ugrad.cs.ubc.ca>
- References: <4e61iu$p6e@villa.fc.net>
- NNTP-Posting-Host: keats.ugrad.cs.ubc.ca
-
- In article <4e61iu$p6e@villa.fc.net>,
- Avinash Chopde <avinash@paranoia.com> wrote:
- >[And no, this is not for a homework exercise.]
- >[BTW, the non-abridged C FAW at http://www.eskimo.com/~scs/C-faq.top.html
- >does not seem to be accessible??]
- >
- >I am trying to find out what could be the fastest way to compute
- >the position of the highest bit in any given integer -- basically, the
- >logarithm to the base 2 of any number.
- >
- >Simplistically, one could do :
- >logbase2(int x)
- >{
- > if (IS_SET_BIT_31(x)) return 31;
- > if (IS_SET_BIT_30(x)) return 30;
- > etc.
- >}
- >
- >An improvement would be to check for BITS_31_16 and BITS_15_0 at first, and
- >then check for BITS_31_24, and BITS_23_16, etc .. (divide problem in half
- >at each stage).
- >
- >Any thoughts or other ideas?
-
- I did something like this a while ago.
-
- The following is a macro which can help you choose the size of an array to fit
- a given number of elements such that the array will have a power of two size
- (good for hashing, or circular lists for example).
-
- /* C macro to round a number up to the nearest power of two */
-
- #ifndef _ROUND_H
- #define _ROUND_H
-
- #define RP2(X) ( \
- (((X)-1) & 0x40000000) ? (0x80000000) : ( \
- (((X)-1) & 0x20000000) ? (0x40000000) : ( \
- (((X)-1) & 0x10000000) ? (0x20000000) : ( \
- (((X)-1) & 0x08000000) ? (0x10000000) : ( \
- (((X)-1) & 0x04000000) ? (0x08000000) : ( \
- (((X)-1) & 0x02000000) ? (0x04000000) : ( \
- (((X)-1) & 0x01000000) ? (0x02000000) : ( \
- (((X)-1) & 0x00800000) ? (0x01000000) : ( \
- (((X)-1) & 0x00400000) ? (0x00800000) : ( \
- (((X)-1) & 0x00200000) ? (0x00400000) : ( \
- (((X)-1) & 0x00100000) ? (0x00200000) : ( \
- (((X)-1) & 0x00080000) ? (0x00100000) : ( \
- (((X)-1) & 0x00040000) ? (0x00080000) : ( \
- (((X)-1) & 0x00020000) ? (0x00040000) : ( \
- (((X)-1) & 0x00010000) ? (0x00020000) : ( \
- (((X)-1) & 0x00008000) ? (0x00010000) : ( \
- (((X)-1) & 0x00004000) ? (0x00008000) : ( \
- (((X)-1) & 0x00002000) ? (0x00004000) : ( \
- (((X)-1) & 0x00001000) ? (0x00002000) : ( \
- (((X)-1) & 0x00000800) ? (0x00001000) : ( \
- (((X)-1) & 0x00000400) ? (0x00000800) : ( \
- (((X)-1) & 0x00000200) ? (0x00000400) : ( \
- (((X)-1) & 0x00000100) ? (0x00000200) : ( \
- (((X)-1) & 0x00000080) ? (0x00000100) : ( \
- (((X)-1) & 0x00000040) ? (0x00000080) : ( \
- (((X)-1) & 0x00000020) ? (0x00000040) : ( \
- (((X)-1) & 0x00000010) ? (0x00000020) : ( \
- (((X)-1) & 0x00000008) ? (0x00000010) : ( \
- (((X)-1) & 0x00000004) ? (0x00000008) : ( \
- (((X)-1) & 0x00000002) ? (0x00000004) : ( \
- (((X)-1) & 0x00000001) ? (0x00000002) : ( \
- 0x00000001 \
- ))))))))))))))))))))))))))))))))
-
-
- #endif
-
- >Thanks!
-
- It essentially does your "is set bit" thing, except that because it is a
- macro, when you use it with a constant argument it will optimize nicely to a
- single load instruction that just fetches the right value. Great for
- compile-time dependencies.
-
- To adapt it to return the bit position, you have to do a little editing, while
- maintaing the essential structure. :)
-
- --
-
-